﻿using System;
using System.Windows;
using System.Linq;
using ALiteTeam.PackageTracer.Core;
using ALiteTeam.PackageTracer.Core.Impl;
using Microsoft.Phone.Scheduler;
using Microsoft.Phone.Shell;
using ALiteTeam.PackageTracer.Data;

namespace ALiteTeam.PackageTracer.RefreshTaskAgent
{
    public class ScheduledAgent : ScheduledTaskAgent
    {
        private static volatile bool _classInitialized;
        private int _UpdatingOrderCount;

        public IDeliveryOperate DeliveryOp { get; set; }
        public IOrderOperate OrderOp { get; set; }
        public ILogWrite LogWriter { get; set; }

        /// <remarks>
        /// ScheduledAgent constructor, initializes the UnhandledException handler
        /// </remarks>
        public ScheduledAgent()
        {
            if (!_classInitialized)
            {
                _classInitialized = true;
                // Subscribe to the managed exception handler
                Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    Application.Current.UnhandledException += ScheduledAgent_UnhandledException;
                });

                InitializeDependency();
            }
        }

        /// Code to execute on Unhandled Exceptions
        private void ScheduledAgent_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                System.Diagnostics.Debugger.Break();
            }

            Settings.AppContext.ExceptionStack.Add(e.ExceptionObject);
            e.Handled = true;
        }

        private void InitializeDependency()
        {
            this.DeliveryOp = DeliveryDataOp.Instance;
            this.OrderOp = new OrderOp();
            this.LogWriter = new GeneralLogWriter();
        }

        /// <summary>
        /// Agent that runs a scheduled task
        /// </summary>
        /// <param name="task">
        /// The invoked task
        /// </param>
        /// <remarks>
        /// This method is called when a periodic or resource intensive task is invoked
        /// </remarks>
        protected override void OnInvoke(ScheduledTask task)
        {
            //TODO: Add code to perform your task in background
            var queue = this.OrderOp.GetQueueForRefresh();
            //var queue = this.OrderOp.GetAll();
            _UpdatingOrderCount = queue.Count;

            foreach (var order in queue)
            {
                QuerySvcOp op = new QuerySvcOp(order);
                op.QuerySummaryCompleted += new EventHandler<QueryEventArgs>(provider_QueryCompleted);

                op.GetSummary();
            }

#if DEBUG
            ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromMinutes(1));
#endif
        }

        void provider_QueryCompleted(object sender, QueryEventArgs e)
        {
            var op = sender as QuerySvcOp;

            // 只有在查询操作成功并且值发生改变之后才触发以下操作：Toast通知，保存已更新的OrderID
            if (e.Success == true && e.Result != op.Order.Summary)
            {
                op.Order.Summary = e.Result;

                var delivery = this.DeliveryOp.DeliveryResource.Deliveries.Where(d => d.ID == op.Order.DeliveryID).FirstOrDefault();
                var result = QueryResult.ParseOrder(e.Result);

                Settings.Configuration.UpdateOrder.Add(op.Order.DeliveryOrderID);

                // 若订单已经被钉在屏幕上，则更新Live Tile
                if (TileHandlerForAgent.Exists(op.Order) == true)
                {
                    TileHandlerForAgent.UpdateSecondaryIile(op.Order);
                }

                if (Settings.Configuration.AllowToast == true)
                {
                    ShellToast toast = new ShellToast();
                    toast.Title = string.Format("{0}{1}", delivery.DisplayName, op.Order.Title);
                    toast.Content = string.Format("{0}", result.Details[0].Context);
                    toast.NavigationUri = new Uri(string.Format(@"/View/Details.xaml?OrderID={0}", op.Order.DeliveryOrderID), UriKind.Relative);
                    toast.Show();
                }
            }

            this.OrderOp.UpdateOrder(op.Order);

            _UpdatingOrderCount--;
            if (_UpdatingOrderCount == 0)
            {
                TileHandlerForAgent.ResetDefaultTile(Settings.Configuration.UpdateOrder.Count);
                NotifyComplete();
            }
        }
    }
}